package se.thoka.twt.client.utils;

import se.thoka.twt.shared.exceptions.SessionTimeoutException;
import se.thoka.twt.shared.exceptions.UserLoginFailedException;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Command;

/**
 * @author Thobias Karlsson, Thoka
 * @since 9 jan 2010
 */
public class ErrorReporter {

	private static ErrorHandler handler;

	/**
	 * This method is called when an RPC request fails.
	 * 
	 * @param caught The exception that caused the error.
	 */
	public static void onRPCError(Throwable caught) {
		onRPCError(caught, null);
	}
	
	/**
	 * This method is called when an RPC request fails.
	 * 
	 * @param caught The exception that caused the error.
	 * @param message A message that could be displayed to user and in logs.
	 */
	public static void onRPCError(Throwable caught, String message) {
		onRPCError(caught, message, null);
	}
	
	/**
	 * This method is called when an RPC request fails.
	 * 
	 * @param caught The exception that caused the error.
	 * @param message A message that could be displayed to user and in logs.
	 * @param subsequentCommand A command to be executed after error has been reported, may be <code>null</code>
	 */
	public static void onRPCError(Throwable caught, String message, Command subsequentCommand) {
		if (caught instanceof UserLoginFailedException) {
			getHandler().onLoginFailed(caught);
		} else if (caught instanceof SessionTimeoutException) {
			getHandler().onSessionTimedOut(caught);
		} else {
			getHandler().onRPCError(caught, message, subsequentCommand);
		}
	}

	/**
	 * This method is called when a general error occurs.
	 * <p>
	 * Note: Use {@link ErrorReporter#onRPCError(Throwable)} if error occurred due to an RPC call.
	 * </p>
	 * 
	 * @param title The error title
	 * @param message The error message
	 * @param caught The exception that caused the error.
	 */
	public static void onError(String title, String message, Throwable caught) {
		onError(title, message, caught, null);
	}

	/**
	 * This method is called when a general error occurs.
	 * <p>
	 * Note: Use {@link ErrorReporter#onRPCError(Throwable)} if error occurred due to an RPC call.
	 * </p>
	 * 
	 * @param title The error title
	 * @param message The error message
	 * @param caught The exception that caused the error.
	 * @param subsequentCommand A command to be executed after error has been reported, may be <code>null</code>
	 */
	public static void onError(String title, String message, Throwable caught, Command subsequentCommand) {
		getHandler().onError(title, message, caught, subsequentCommand);
	}

	/**
	 * Touches this exception handler.
	 * <p>
	 * This method should be called from the application initialization point as soon as possible to make us handle uncaught exceptions
	 * </p>
	 */
	public static void touch() {
		getHandler();
	}

	private static ErrorHandler getHandler() {
		if (handler == null) {
			handler = GWT.create(ErrorHandler.class);

			if (handler.handlesUncaughtExceptions()) {
				GWT.setUncaughtExceptionHandler(handler);
			}
		}

		return handler;
	}
}
